<template>
    <div class="images-container">
        <div
            class="image-item"
            @click="compControl.viewer.handleShow(item, index)"
            v-for="(item, index) in compControl.image_store.computed_render_array"
            :key="index">
            <img class="image" :src="'data:image/jpeg;base64,' + item.data" :alt="item.filename" />
        </div>
    </div>
    <footer class="controller-footer">
        <n-space>
            <n-button @click="compControl.footer_btns.handleBack" size="tiny" color="purple">
                back
            </n-button>
            <n-button
                :disabled="!Boolean(compControl.footer_btns.current_recycle_bin_count)"
                @click="compControl.footer_btns.handleRecycleBin('open')"
                size="tiny"
                type="info">
                打开回收站
            </n-button>
            <n-popconfirm
                @positive-click="compControl.footer_btns.handleRecycleBin('clean')"
                @negative-click=""
                :negative-button-props="{ size: 'tiny' }"
                :positive-button-props="{ size: 'tiny' }">
                <template #trigger>
                    <n-button
                        size="tiny"
                        type="error"
                        :disabled="!Boolean(compControl.footer_btns.current_recycle_bin_count)">
                        清空回收站[{{ compControl.footer_btns.current_recycle_bin_count }}]
                    </n-button>
                </template>
                确认清空回收站？
            </n-popconfirm>
            <n-checkbox
                id="ckbox-DOM-Refresh"
                size="small"
                v-model:checked="compControl.footer_btns.enable_refresh_dom">
                <span style="font-size: smaller">开关DOM刷新</span>
            </n-checkbox>
        </n-space>
        <n-space>
            <n-pagination
                v-model:page="compControl.pagination.current_page"
                v-model:page-size="compControl.pagination.current_page_size"
                :page-count="compControl.pagination.page_count"
                size="small"
                show-size-picker
                :page-sizes="[50, 100, 200]" />
            <div>{{ compControl.image_store.array.length }}个</div>
        </n-space>
    </footer>
    <hr class="controller-footer-seperator" />

    <n-modal v-model:show="compControl.viewer.show" @after-leave="compControl.viewer.handleClose()" >
        <n-card
            style="width: 80%; max-height: 90vh"
            :bordered="false"
            size="small"
            role="dialog"
            aria-modal="true"
            id="viewer">
            <template #header>
                <p style="margin: 0; text-align: center">
                    [{{ compControl.viewer.current_index }}]{{ compControl.viewer.computed_short_name }}
                </p>
            </template>
            <template #header-extra>
                <span @click="compControl.viewer.handleClose()" class="close-btn">
                    <svg
                        xmlns="http://www.w3.org/2000/svg"
                        width="16"
                        height="16"
                        viewBox="3 3 10 10"
                        class="close-btn">
                        <path
                            d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708" />
                    </svg>
                </span>
            </template>
            <img
                style="object-fit: scale-down; width: 100%; height: auto"
                :src="'data:image/jpeg;base64,' + compControl.viewer.current_data.data"
                :alt="compControl.viewer.current_data.filename" />
            <template #footer>
                <n-space style="width: 100%; padding: 0 0.5rem" justify="space-between">
                    <div style="position: relative">
                        <div style="position: absolute; left: 0">
                            <span
                                style="color: green; white-space: nowrap"
                                v-if="compControl.viewer.current_data.picked == true">
                                picked√
                            </span>
                            <span
                                style="color: red; white-space: nowrap"
                                v-else-if="compControl.viewer.current_data.picked == false">
                                unpicked
                            </span>
                            <span
                                style="color: red; white-space: nowrap"
                                v-else-if="compControl.viewer.current_data.deleted">
                                已删除
                                <span style="opacity: 0.375">(未刷新)</span>
                            </span>
                        </div>
                    </div>
                    <n-space>
                        <n-button
                            size="tiny"
                            @click="compControl.viewer.handleSwitchImage('prev')"
                            :disabled="compControl.viewer.current_index == 0">
                            ←上一张
                        </n-button>
                        <n-button
                            size="tiny"
                            @click="compControl.viewer.handlePickup('pick')"
                            secondary
                            type="primary">
                            ↑Pick
                        </n-button>
                        <n-button
                            size="tiny"
                            @click="compControl.viewer.handlePickup('unpick')"
                            secondary
                            type="warning">
                            Unpick↓
                        </n-button>
                        <n-button
                            size="tiny"
                            @click="compControl.viewer.handleSwitchImage('next')"
                            :disabled="
                                compControl.viewer.current_index ==
                                compControl.image_store.array.length - 1
                            ">
                            下一张→
                        </n-button>
                    </n-space>
                    <div style="position: relative">
                        <n-space
                            style="position: absolute; right: 0"
                            justify="end"
                            align="center"
                            :wrap="false">
                            <div style="white-space: nowrap; padding-top: 1px">
                                第{{ compControl.viewer.current_index + 1 }}个
                            </div>
                            <n-button
                                size="tiny"
                                @click="compControl.viewer.handleDelete('delete')"
                                type="error"
                                secondary>
                                删除文件
                            </n-button>
                            <n-button
                                size="tiny"
                                @click="compControl.viewer.handleDelete('open')"
                                type="error"
                                secondary>
                                打开回收站
                            </n-button>
                        </n-space>
                    </div>
                </n-space>
            </template>
        </n-card>
    </n-modal>
</template>
<script setup lang="ts">
import { watch, computed, onMounted, reactive, nextTick } from 'vue'
import {
    NButton,
    NPagination,
    NSpace,
    NModal,
    NCard,
    useMessage,
    NPopconfirm,
    NSwitch,
    NCheckbox
} from 'naive-ui'
//@ts-ignore
import { GetFileB64, CopyFileToPickedFolder, RecycleBinController } from '@wails/go/main/App'
//////////////////////////////////////////////
interface ImageItem {
    data: Blob
    filename: string
    picked?: boolean
    deleted?: boolean
    url?: string
}
//////////////////////////////////////////////

const message = useMessage()
//////////////////////////////////////////////

//////////////////////////////////////////////
const compControl = reactive({
    image_store: {
        array: [] as Array<ImageItem>,
        computed_render_array: computed(() => {
            return compControl.image_store.array.slice(
                compControl.pagination.index_start,
                compControl.pagination.index_end
            )
        }),
        async handleGetImageArray() {
            for (let i = 0; i < props.data.length; i++) {
                const item = props.data[i]
                compControl.image_store.array.push({
                    filename: item,
                    data: await GetFileB64(item)
                })
            }
        }
    },
    pagination: {
        current_page: 1,
        current_page_size: 50,
        index_start: computed(() => {
            let t = (compControl.pagination.current_page - 1) * compControl.pagination.current_page_size
            return t
        }),
        index_end: computed(() => {
            let t = compControl.pagination.index_start + compControl.pagination.current_page_size
            if (t > compControl.image_store.array.length) {
                t = compControl.image_store.array.length
            }
            return t
        }),
        page_count: computed(() => {
            return Math.ceil(
                compControl.image_store.array.length / compControl.pagination.current_page_size
            )
        })
    },
    viewer: {
        show: false,
        current_data: {} as ImageItem,
        current_index: 0,
        computed_short_name: computed<string>(() => {
            const s: Array<string> = compControl.viewer.current_data.filename.split('/')
            return s[s.length - 1]
        }),
        handleShow(item, index) {
            compControl.viewer.current_data = item
            compControl.viewer.current_index = compControl.pagination.index_start + index
            compControl.viewer.show = true
            window.addEventListener('keydown', compControl.viewer.handleArrowKeyInput)
        },
        handleClose() {
            window.removeEventListener('keydown', compControl.viewer.handleArrowKeyInput)
            compControl.viewer.show = false
        },
        handleSwitchImage(action: 'prev' | 'next' | 'refresh_current') {
            if (action == 'prev') {
                if (compControl.viewer.current_index == 0) {
                    return
                }
                compControl.viewer.current_data =
                    compControl.image_store.array[compControl.viewer.current_index - 1]
                compControl.viewer.current_index -= 1
                if (compControl.viewer.current_index < compControl.pagination.index_start) {
                    compControl.pagination.current_page -= 1
                }
            } else if (action == 'next') {
                if (compControl.viewer.current_index == compControl.image_store.array.length - 1) {
                    return
                }
                compControl.viewer.current_data =
                    compControl.image_store.array[compControl.viewer.current_index + 1]
                compControl.viewer.current_index += 1
                if (compControl.viewer.current_index > compControl.pagination.index_end) {
                    compControl.pagination.current_page += 1
                }
            } else if (action == 'refresh_current') {
                compControl.viewer.current_data =
                    compControl.image_store.array[compControl.viewer.current_index]
            }
        },
        async handlePickup(action = 'pick') {
            try {
                await CopyFileToPickedFolder(compControl.viewer.current_data.filename, action)
                compControl.image_store.array[compControl.viewer.current_index]['picked'] = Boolean(
                    action == 'pick'
                )
            } catch (error) {
                message.error(error)
            }
        },
        async handleDelete(action: 'delete' | 'open' = 'delete') {
            try {
                await RecycleBinController(compControl.viewer.current_data.filename, action)
                if (action == 'open') {
                    return
                }
                if (action == 'delete') {
                    const enableRefresh = compControl.footer_btns.enable_refresh_dom
                    compControl.viewer.current_data['deleted'] = true
                    if (enableRefresh) {
                        await compControl.image_store.array.splice(compControl.viewer.current_index, 1)
                        const isLastItem =
                            compControl.viewer.current_index === compControl.image_store.array.length
                        compControl.viewer.handleSwitchImage(isLastItem ? 'prev' : 'refresh_current')
                    } else {
                        compControl.viewer.handleSwitchImage('next')
                    }
                    message.success('操作成功!')
                    await compControl.footer_btns.handleGetRecycleBinCount()
                }
            } catch (error) {
                message.error(error)
            }
        },

        handleArrowKeyInput(event) {
            switch (event.key) {
                case 'ArrowUp':
                    compControl.viewer.handlePickup('pick')
                    break
                case 'ArrowDown':
                    compControl.viewer.handlePickup('unpick')
                    break
                case 'ArrowLeft':
                    compControl.viewer.handleSwitchImage('prev')
                    break
                case 'ArrowRight':
                    compControl.viewer.handleSwitchImage('next')
                    break
            }
        }
    },
    footer_btns: {
        current_recycle_bin_count: 0,
        enable_refresh_dom: true,

        handleBack() {
            compControl.image_store.array = []
            emit('action:back')
        },
        async handleRecycleBin(action: 'open' | 'clean') {
            if (action == 'open' || 'clean') {
                try {
                    await RecycleBinController(compControl.image_store.array[0].filename, action)
                    if (action == 'clean') {
                        message.success('操作成功!')
                    }
                } catch (error) {
                    message.error(error)
                }
            }
        },
        async handleGetRecycleBinCount() {
            try {
                await RecycleBinController(compControl.image_store.array[0].filename, 'count')
            } catch (returns) {
                compControl.footer_btns.current_recycle_bin_count = parseInt(returns)
            }
        }
    }
})
watch(
    () => compControl.pagination.index_start,
    (nv, ov) => {
        //console.log(ov);
    },
    { deep: true, immediate: true }
)

///////////////////////////////////////////////////

const props = defineProps({
    data: { type: Object, default: [] }
})
const emit = defineEmits(['action:back'])
onMounted(async () => {
    await compControl.image_store.handleGetImageArray()
    await compControl.footer_btns.handleGetRecycleBinCount()
})
</script>

<style scoped lang="scss">
$header_height: 2.5rem;

.images-container {
    padding: 20px;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
    //grid-template-rows: 120px;
    gap: 10px;
    box-sizing: border-box;

    .image-item {
        cursor: pointer;
        border: 1px solid #ddd;
        border-radius: 4px;
        padding: 10px;
        background: #f9f9f9;
        max-width: 350px;

        .image {
            width: 100%;
            max-width: 300px;
            height: min-content;
            max-height: 200px;
            object-fit: contain;
            display: block;
        }

        .image-path {
            margin-top: 8px;
            word-break: break-all;
        }
    }
}

.controller-footer {
    width: 100%;
    position: fixed;
    z-index: 1;
    bottom: 0;
    left: 0;
    background-color: #f3f3f3;
    border-top: 1px solid green;
    padding: 0.5rem 1rem;
    height: 2rem;
    box-sizing: border-box;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

hr.controller-footer-seperator {
    height: $header_height;
    border: none;
    margin: 0;
}

#viewer {
    :deep(.n-card__content) {
        display: flex;
        overflow: hidden;
    }

    :deep(.n-card-header) {
        padding: 2px 0.25rem !important;
        font-size: 0.75rem;
        line-height: 0.75rem;
    }

    .close-btn {
        svg:hover {
            fill: orange;
            cursor: pointer;
        }
    }
}

#image-scroll-container {
    overflow: auto;
    height: calc(100vh - $header_height);
    display: grid;
    padding: 20px;
    grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
    grid-template-rows: 120px;
    gap: 8px;
    box-sizing: border-box;
}

#ckbox-DOM-Refresh {
    flex-direction: row-reverse;
    .n-checkbox__label {
        padding-right: 0.25rem;
    }
}
</style>
